/*
 * @Author: wangjh wangjiahui0710@163.com
 * @Date: 2024-05-20 16:40:44
 * @LastEditors: wangjh wangjiahui0710@163.com
 * @LastEditTime: 2024-05-23 15:22:43
 * @FilePath: \hn-fire-product-mobile\src\hooks\use-async.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
export interface UseAsyncOptions {
  /**
   * Delay for executing the promise. In milliseconds.
   *
   * @default 0
   */
  delay?: number;
  /**
   * Execute the promise right after the function is invoked.
   * Will apply the delay if any.
   *
   * When set to false, you will need to execute it manually.
   *
   */
  immediate?: boolean;

  /**
   * Callback when error is caught.
   */
  onError?: (e: unknown) => void;
  /**
   * Callback when success is caught.
   * @param {D} data
   */
  onSuccess?: (data: any) => void;
  /**
   * Sets the state to initialState before executing the promise.
   *
   * This can be useful when calling the execute function more than once (for
   * example, to refresh data). When set to false, the current state remains
   * unchanged until the promise resolves.
   *
   * @default true
   */

  /**
   *
   * An error is thrown when executing the execute function
   *
   * @default false
   */
  throwError?: boolean;
}

export interface UseAsyncReturn<Params extends any[]> {
  isReady: Ref<boolean>;
  isLoading: Ref<boolean>;
  error: Ref<unknown>;
  execute: (delay?: number, ...args: Params) => Promise<any>;
}

export function useAsync<Params extends any[]>(
  promise: Promise<any> | ((...args: Params) => Promise<any>),
  options: UseAsyncOptions = {},
): UseAsyncReturn<Params> {
  const { isReady, isLoading, execute, error } = useAsyncState(promise, undefined, {
    ...options,
    immediate: options.immediate ?? false,
  });
  return {
    isReady,
    isLoading,
    execute,
    error,
  };
}
